package kr.ac.sch.cs.HelloBabyServer.UI;

import java.io.IOException;
import java.net.SocketException;
import java.net.UnknownHostException;

import org.sipdroid.net.RtpPacket;
import org.sipdroid.net.RtpSocket;
import org.sipdroid.net.SipdroidSocket;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.Log;


public class SocketCamera {
/**
 * @uml.property  name="mIsRunning"
 */
private volatile boolean mIsRunning = false;
	
	/**
	 * @uml.property  name="rtp_socket"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private RtpSocket rtp_socket = null;
	/**
	 * @uml.property  name="rev_socket"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private SipdroidSocket rev_socket = null;
	/**
	 * @uml.property  name="rtp_packet"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private RtpPacket rtp_packet = null;
	
	/**
	 * @uml.property  name="bounds"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private final Rect bounds;
	/**
	 * @uml.property  name="preserveAspectRatio"
	 */
	private final boolean preserveAspectRatio;
	/**
	 * @uml.property  name="paint"
	 * @uml.associationEnd  multiplicity="(1 1)"
	 */
	private final Paint paint = new Paint();
	/**
	 * @uml.property  name="buffer" multiplicity="(0 -1)" dimension="1"
	 */
	private byte[] buffer;
	
	public SocketCamera(int port, int width, int height, boolean preserveAspectRatio) {
		bounds = new Rect(0, 0, width, height);
		this.preserveAspectRatio = preserveAspectRatio;
		try {
			rev_socket = new SipdroidSocket(port);
		} catch (SocketException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnknownHostException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		rtp_socket = new RtpSocket(rev_socket);
		
		paint.setFilterBitmap(true);
		paint.setAntiAlias(true);
		
		buffer = new byte[500000];
		rtp_packet = new RtpPacket(buffer, 0);
	}
	
	public int getWidth() {
		return bounds.right;
	}
	
	public int getHeight() {
		return bounds.bottom;
	}
	
	public boolean open() {
		/* nothing to do */
		return true;
	}
	
	public boolean capture(Canvas canvas) {
		if (canvas == null) throw new IllegalArgumentException("null canvas");
		if (rtp_socket == null) {
			return false;
		}
		try {

			rtp_socket.receive(rtp_packet);
			Bitmap bitmap = BitmapFactory.decodeByteArray(rtp_packet.getPayload(), 0 , rtp_packet.getPayloadLength());
			
			/*
			Matrix m = new Matrix();           
			m.setRotate( -90, (float)bitmap.getWidth()/2, (float)bitmap.getHeight()/2);           

			Bitmap imageTemp = Bitmap.createBitmap(bitmap, 0, 0,  bitmap.getWidth(), bitmap.getHeight(), m, true );      
			if (bitmap != imageTemp) {         
				bitmap.recycle();                 
				bitmap = imageTemp;           
			} 
			*/
			//render it to canvas, scaling if necessary
			if (
					bounds.right == bitmap.getWidth() &&
					bounds.bottom == bitmap.getHeight()) {
				canvas.drawBitmap(bitmap, 0, 0, null);
			} else {
				Rect dest;
				if (preserveAspectRatio) {
					dest = new Rect(bounds);
					dest.bottom = bitmap.getHeight() * bounds.right / bitmap.getWidth();
					dest.offset(0, (bounds.bottom - dest.bottom)/2);
				} else {
					dest = bounds;
				}
				canvas.drawBitmap(bitmap, null, dest, paint);
			}

		} catch (RuntimeException e) {
			Log.i("socketCamera", "Failed to obtain image over network", e);
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (OutOfMemoryError ex) {} 
		
		return true;
	}

	public void close() {
		/* nothing to do */
	}
}
